﻿using System;
using fastCSharp;
using System.Collections.Generic;

namespace diantou.examLogServer
{
    /// <summary>
    /// 考试编程日志
    /// </summary>
    [fastCSharp.code.cSharp.tcpCall(Service = "ExamLog")]
    [diantou.dataModel.sqlTable(Connection = diantou.dataModel.sqlTable.connection.ExamLog)]
    public partial class examJudgeLog : diantou.dataModel.examJudgeLog.sqlModel<examJudgeLog>
    {
        /// <summary>
        /// 日志类型
        /// </summary>
        public byte IntType
        {
            get { return (byte)Type; }
        }
        /// <summary>
        /// 获取用户考试日志
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="problemId"></param>
        /// <returns></returns>
        [fastCSharp.code.cSharp.tcpMethod]
        private static examJudgeLog[] get(int userId, int problemId)
        {
            logs logs = examUser.Get(userId).JudgeLog;
            return logs == null ? userCache[userId].Get(problemId).ToArray() : logs.Get(problemId).ToArray();
        }

        /// <summary>
        /// 添加考试编程日志
        /// </summary>
        /// <param name="userId"></param>
        /// <param name="sessionId"></param>
        /// <param name="logs"></param>
        /// <returns></returns>
        [fastCSharp.code.cSharp.tcpMethod]
        private static bool append(int userId, int sessionId, examJudgeLog[] logs)
        {
            if (examUser.Get(userId).CheckSessionId(sessionId))
            {
                batchImport.Append(logs, true);
                return true;
            }
            return false;
        }

        /// <summary>
        /// 用户问题日志集合
        /// </summary>
        internal sealed class logs : fastCSharp.sql.cache.ICustom<examJudgeLog>
        {
            /// <summary>
            /// 用户标识
            /// </summary>
            private int userId;
            /// <summary>
            /// 问题日志集合
            /// </summary>
            private subArray<keyValue<int, list<examJudgeLog>>> problemLogs;
            /// <summary>
            /// 所有缓存数据
            /// </summary>
            public IEnumerable<examJudgeLog> Values
            {
                get
                {
                    if (problemLogs.Count != 0)
                    {
                        foreach (keyValue<int, list<examJudgeLog>> logs in problemLogs.UnsafeArray)
                        {
                            if (logs.Value != null)
                            {
                                foreach (examJudgeLog log in logs.Value) yield return log;
                            }
                        }
                    }
                }
            }
            /// <summary>
            /// 用户问题日志集合
            /// </summary>
            /// <param name="userId"></param>
            public logs(int userId)
            {
                this.userId = userId;
                examJudgeLog[] logs = sqlTable.Where(value => value.UserId == userId).getSubArray().getSort(value => value.Times);
                keyValue<int, list<examJudgeLog>> problemLog = default(keyValue<int, list<examJudgeLog>>);
                foreach (examJudgeLog log in logs)
                {
                    if (log.Type == type.LoadAce && problemLog.Key != log.StartRow)
                    {
                        if ((problemLog.Value = createLogs(problemLog.Key = log.StartRow)) == null)
                        {
                            problemLog.Value = new list<examJudgeLog>();
                            problemLogs.Add(problemLog);
                        }
                    }
                    problemLog.Value.Add(log);
                }
            }
            /// <summary>
            /// 创建日志集合
            /// </summary>
            /// <param name="problemId"></param>
            /// <returns></returns>
            private list<examJudgeLog> createLogs(int problemId)
            {
                if (problemLogs.Count != 0)
                {
                    foreach (keyValue<int, list<examJudgeLog>> logs in problemLogs.UnsafeArray)
                    {
                        if (logs.Key == problemId) return logs.Value;
                    }
                }
                return null;
            }
            /// <summary>
            /// 添加缓存数据
            /// </summary>
            /// <param name="value">缓存数据</param>
            /// <returns>是否添加数据</returns>
            public bool Add(examJudgeLog value)
            {
                userCache.Remove(userId);
                return false;
            }
            /// <summary>
            /// 更新缓存数据
            /// </summary>
            /// <param name="value">缓存数据</param>
            /// <param name="oldValue">旧数据</param>
            /// <returns>添加数据返回正数，删除数据返回负数，没有变化返回0</returns>
            public int Update(examJudgeLog value, examJudgeLog oldValue)
            {
                userCache.Remove(userId);
                return 0;
            }
            /// <summary>
            /// 删除缓存数据
            /// </summary>
            /// <param name="value">缓存数据</param>
            /// <returns>是否存在被删除数据</returns>
            public bool Remove(examJudgeLog value)
            {
                userCache.Remove(userId);
                return false;
            }
            /// <summary>
            /// 获取日志
            /// </summary>
            /// <param name="problemId"></param>
            /// <returns></returns>
            public subArray<examJudgeLog> Get(int problemId)
            {
                if (problemLogs.Count != 0)
                {
                    foreach (keyValue<int, list<examJudgeLog>> logs in problemLogs.UnsafeArray)
                    {
                        if (logs.Key == problemId) return logs.Value.ToSubArray();
                    }
                }
                return default(subArray<examJudgeLog>);
            }
        }
        /// <summary>
        /// 批量导入日志
        /// </summary>
        private static readonly fastCSharp.sql.batchImport<examJudgeLog, dataModel.examJudgeLog> batchImport;
        /// <summary>
        /// 用户日志缓存
        /// </summary>
        private static readonly fastCSharp.sql.cache.part.memberQueueCustom<examJudgeLog, dataModel.examJudgeLog, examUser, int, logs> userCache;
        static examJudgeLog()
        {
            if (sqlTable != null)
            {
                userCache = new fastCSharp.sql.cache.part.memberQueueCustom<examJudgeLog, dataModel.examJudgeLog, examUser, int, logs>(sqlTable, value => value.UserId, examUser.Get, userId => new logs(userId), value => value.JudgeLog, value => value.PreviousJudgeLogNode, value => value.NextJudgeLogNode);

                batchImport = new fastCSharp.sql.batchImport<examJudgeLog, dataModel.examJudgeLog>(sqlTable, 512);
                sqlTable.LoadWait.Set();
                if (fastCSharp.config.appSetting.IsCheckMemory) checkMemory.Add(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
            }
        }
    }
}
